//
//  BaseRequest.m
//  iPhoneKML
//
//  Created by Benjamin Blundell on 16/10/2009.
//  Copyright 2009 Centre for Advanced Spatial Analysis. All rights reserved.
//

#import "BaseRequest.h"

#define DEBUG

@interface BaseRequest (private)

- (void)startRequest;
- (void)clearUrlConnection;

@end


@implementation BaseRequest

@synthesize delegate; 
@synthesize request; 
@synthesize response;
@synthesize postVars; 
@synthesize commandVars; 
@synthesize headerVars;
@synthesize baseURLString;

#pragma mark Accessor Methods

- (NSData *)data {
	return [[data copy] autorelease];
}

- (NSString *)stringData {
	return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
}

#pragma mark Setup and Teardown Methods

- (id)initWithBaseURL:(NSString *)baseURL {
	self = [super init];
	if (self != nil)
	{
		baseURLString = [[NSMutableString alloc] init];
		commandVars = [[NSMutableString alloc] init];
		headerVars = [[NSMutableDictionary alloc] init];
		delegate = nil;
		request = nil;
		response = nil;
		urlConnection = nil;
		data = nil;
		timeout = 20;
		[baseURLString appendString:baseURL];
	}
	
	return self;	
}

- (id)init {
	return [self initWithBaseURL:@""];
}

- (void) dealloc {
	self.baseURLString = nil;
	[request release];
	[commandVars release];
	[headerVars release];
	[response release];
	[urlConnection release];
	[data release];
	[postVars release];
	
	[super dealloc];
}


#pragma mark Public Methods

- (void)performRequest {	
	
	// build the request object
	NSMutableString *fullURL = [[NSMutableString alloc] init];
	if (baseURLString)
		[fullURL appendString:baseURLString];
	else
		[fullURL appendString:@"http://www.talesofthings.com"];
	
	if (commandVars)
		[fullURL appendString:commandVars];
	
	
	
	request = [NSMutableURLRequest requestWithURL:[ NSURL URLWithString:fullURL]
									  cachePolicy:NSURLRequestUseProtocolCachePolicy
								  timeoutInterval:timeout];
#ifdef DEBUG
	NSLog(@"Doing Requst with: %@",fullURL );
#endif
	
	[fullURL release];
	
	// set the header variables
	if (headerVars) {
		for (id key in [headerVars allKeys]){
			[request setValue: [headerVars valueForKey:key] forHTTPHeaderField:key];
		}
	}
	
	
	// Convert the post variables to a json string
	// Set as a POST. May need to change this over time
	
	if (postVars){
#ifdef DEBUG
		NSLog(@"POST vars: %@",postVars );
#endif
		
		
		NSMutableString *post = [[NSMutableString alloc] init];
		
		for (id key in [postVars allKeys]){
			[post appendString: key];
			[post appendString: @"="];
			[post appendString: [postVars valueForKey:key]];
			[post appendString: @"&"];
		}
	
		// Strip last &
		NSString *substring = [post substringToIndex:[post length] -2 ];
		
		NSData *postData = [substring dataUsingEncoding:NSASCIIStringEncoding
							  allowLossyConversion:NO];
		
		
		//NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
		[request setHTTPBody:postData];
		[request setHTTPMethod: @"POST"];
		
		[post release];
	}
	
	[self startRequest];
}


#pragma mark Private Methods

- (void)startRequest {
	if (delegate != nil)
		[delegate willSendRequest:request];
	
	// Clear any previous data and setup to collect the response and response data.
	
	[data release];
	data = [NSMutableData new];
	[response release];
	response = nil;
	
	
#ifdef DEBUG
	NSLog(@"Sending Request");
#endif
	// Load the URL.
	urlConnection = [[NSURLConnection connectionWithRequest:request delegate:self] retain];
}	

- (void)clearUrlConnection {
	
	[commandVars release];
	[postVars release];
	
	if (urlConnection != nil)
	{
		[urlConnection release];
		urlConnection = nil;
	}
	
	if (delegate != nil)
		[delegate finishedReceivingData:self.data];
}


- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)aRequest redirectResponse:(NSURLResponse *)aResponse; {
#ifdef DEBUG
	NSLog(@"In connection: willSendRequest: %@ redirectResponse: %@", aRequest, aResponse);
#endif
	return aRequest;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; {
#ifdef DEBUG
	NSLog(@"In connection: didReceiveAuthenticationChallenge: %@", challenge);
#endif
}

- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; {
#ifdef DEBUG
	NSLog(@"In connection: didCancelAuthenticationChallenge: %@", challenge);
#endif
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse; {
#ifdef DEBUG
	NSLog(@"connection: didReceiveResponse: %@, %lld", [aResponse URL], [aResponse expectedContentLength]);
#endif
	
	response = [aResponse retain];
	if (delegate != nil)
		[delegate didReceiveResponse:response];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)newData; {
#ifdef DEBUG
	NSLog(@"In connection: didReceiveData:");
#endif
	[data appendData:newData];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
#ifdef DEBUG
	NSLog(@"In connectionDidFinishLoading: %@" , [self stringData]);
#endif
	[self clearUrlConnection];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
{
#ifdef DEBUG
	NSLog(@"In connection: didFailWithError: %@", error);
#endif
	
	[self clearUrlConnection];
	if (delegate != nil)
		[delegate didFailWithError:error];
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
{
#ifdef DEBUG
	NSLog(@"connection: willCacheResponse:");
#endif
	return nil;
}



@end
